package service;

import entity.Goods;
import entity.Order;
import util.Result;

import java.util.Arrays;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 商品管理类
 */

public class GoodsManagement {

    public GoodsManagement(){
        this.storeGoods = new Goods[10];
        this.sellGoods = new Goods[10];
    }

    private Goods[] storeGoods;//库存商品
    private Goods[] sellGoods;//已售商品

    //AtomicLong支持在并发环境下，自动递增生成一个long类型的数字
    //mysql中的auto_increment相似，从1开始累加
    private AtomicLong atomicLong = new AtomicLong();

    //保存库存商品的数量
    private int store_size = 0;
    //保存已售商品的数量
    private int sell_size = 0;

    //首先要有库存
    int count_store = 0;

    //卖出去的量
    int cout_sell = 0;


    //添加商品
    public Result add_Merchandise(Goods goods){
        //扩容商品
        if (this.count_store + 1 > this.storeGoods.length){
            
            int old_ster = this.storeGoods.length;
            int newLength = old_ster + (old_ster / 2);
            this.storeGoods = Arrays.copyOf(storeGoods,newLength);
        }

        //验证是否存在这个商品
        for (int i = 0; i < this.store_size; i++) {
            Goods $goods = this.storeGoods[i];
            if ($goods.getName().equals(goods.getName())){
                $goods.setCount($goods.getCount() + goods.getCount());//累加数量
                $goods.setPrice(goods.getPrice()); //修改价格
                $goods.setShellPrice(goods.getShellPrice());
                $goods.setType(goods.getType());
                return new Result(0,"数据更改成功",goods);
            }
        }
        //生成唯一的商品编号
        long goodsId = atomicLong.getAndIncrement();
        goods.setGoodsId((int) goodsId);//为新录入的商品设置编号

        this.storeGoods[this.store_size++] = goods;
        return new Result(0, "数据录入成功",goods);
    }

    /*
     * 2.根据商品编号删除商品信息
     * */
    public Result removeById(long goodsId) {
        //遍历商品的数组
        for (int i = 0; i < this.store_size; i++) {
            //每次循环取出每一个商品
            Goods storeGood = storeGoods[i];
            //编号存在
            if (storeGood.getGoodsId() == goodsId) {
                //删除商品
                /*
                    基于jvm底层实现的一个对数组复制的方法
                    Arrays.copyOf就是基于System.arraycopy()方法实现的
                System.arraycopy()

                第一个参数：src，被复制的源数组
                第二个参数：srcPos,被复制的源数组的起始下标
                第三个参数：dest，用于接收的目标数组
                第四个参数：destPos,接收数组接收的起始下标
                第五个参数：length，从源数组中复制几个元素
                * */
                System.arraycopy(this.storeGoods, i + 1, this.storeGoods, i, this.store_size - 1 - i);

                //让实际元素个数-1
                this.store_size--;
                this.storeGoods[this.store_size] = null;
                return new Result(0,"删除成功",storeGood);
            }
        }
        return new Result(1, "不存在此商品信息");
    }

    /*
     * 3.根据商品编号查询商品信息
     * */
    public Result findGoodsById(long goodsId) {
        //遍历商品对象数组，根据编号匹配商品
        for (int i = 0; i < this.store_size; i++) {
            Goods goods = this.storeGoods[i];
            if (goods.getGoodsId() == goodsId) { //找到了相同编号的商品
                Result result = new Result();
                result.setNessage("查询成功");
                result.setData(goods);
                return result;
            }
        }
        Result fail = Result.fail();
        fail.setNessage("查无此商品信息");
        return fail;
    }

    /*4.根据商品类别查询商品信息，并且根据商品库存数量排序*/
    public Result findByType(String type){
        //第一步，知道该type的数量有多少个
        int size = 0;
        for (int i = 0; i < this.store_size; i++) {
            //取出每一个商品
            Goods goods = this.storeGoods[i];
            if (goods.getType().equals(type)) {
                size++;
            }
        }
        //验证是否存在该类型的商品，如果没有，size为0，则立刻返回没有该类型商品
        if (size == 0) {
            Result result = new Result();
            result.setCode(1);
            result.setNessage("查无此类型商品");
        }

        //第二步，创建指定长度的数组
        Goods[] $goods = new Goods[size];

        //第三步，遍历store_goods,将对应type添加到$goods数组中
        int index = 0;
        for (int i = 0; i < this.store_size; i++) {
            //取出每一个商品
            Goods goods = this.storeGoods[i];
            if (goods.getType().equals(type)) {
                $goods[index++] = goods;
            }
        }

        //第四步，对对象数组排序
        for (int i = 0; i < $goods.length - 1; i++) {
            for (int j = 0; j < $goods.length - 1 - i; j++) {
                //分别获取要比较的数量
                Goods tmp1 = $goods[j];
                Goods tmp2 = $goods[j + 1];
                //注意：对象不能直接比较。
                if (tmp1.getCount() > tmp2.getCount()) {
                    $goods[j] = tmp2;
                    $goods[j + 1] = tmp1;
                }
            }
        }

        //第四步，返回数据
        Result result = new Result();
        result.setNessage("查询成功");
        result.setData($goods);//将数组保存到data
        return result;
    }


    /*5.查询库存不足10的商品信息,结果根据商品售价排序*/
    public Result storeLessThan10(){
        //第一步，知道该type的数量有多少个
        int size = 0;
        for (int i = 0; i < this.store_size; i++) {
            //取出每一个商品
            Goods goods = this.storeGoods[i];
            if (goods.getCount() < 10) {
                size++;
            }
        }
        //验证是否存在该类型的商品，如果没有，size为0，则立刻返回没有该类型商品
        if (size == 0) {
            Result result = new Result();
            result.setCode(1);
            result.setNessage("查无此库存");
        }

        //第二步，创建指定长度的数组
        Goods[] $goods = new Goods[size];

        //第三步，遍历store_goods,将对应type添加到$goods数组中
        int index = 0;
        for (int i = 0; i < this.store_size; i++) {
            //取出每一个商品
            Goods goods = this.storeGoods[i];
            if (goods.getCount() < 10) {
                $goods[index++] = goods;
            }
        }

        //第四步，对对象数组排序
        for (int i = 0; i < $goods.length - 1; i++) {
            for (int j = 0; j < $goods.length - 1 - i; j++) {
                //分别获取要比较的数量
                Goods tmp1 = $goods[j];
                Goods tmp2 = $goods[j + 1];
                //注意：对象不能直接比较。
                if (tmp1.getCount() > tmp2.getCount()) {
                    $goods[j] = tmp2;
                    $goods[j + 1] = tmp1;
                }
            }
        }

        //第四步，返回数据
        Result result = new Result();
        result.setNessage("查询成功");
        result.setData($goods);//将数组保存到data
        return result;
    }


    /*6.统计最贵的商品信息（销售价格），可能有多个*/
    public Result findByMaxSellPrice(){
        //验证是否存在该类型的商品，如果没有，size为0，则立刻返回没有该类型商品
        if (this.store_size == 0) {
            Result result = new Result();
            result.setCode(1);
            result.setNessage("暂无库存");
            return result;
        }


        //1.确定最高价格是多少
        double max = 0;
        for (int i = 0; i < this.store_size; i++) {
            Goods storeGood = this.storeGoods[i];
            if (storeGood.getShellPrice() > max) {
                max = storeGood.getShellPrice();
            }
        }

        //第一步，知道该type的数量有多少个
        int size = 0;
        for (int i = 0; i < this.store_size; i++) {
            //取出每一个商品
            Goods goods = this.storeGoods[i];
            if (goods.getShellPrice() == max) { //只要价格是最高的商品，就累加数量
                size++;
            }
        }


        //第二步，创建指定长度的数组
        Goods[] $goods = new Goods[size];

        //第三步，遍历store_goods,将对应type添加到$goods数组中
        int index = 0;
        for (int i = 0; i < this.store_size; i++) {
            //取出每一个商品
            Goods goods = this.storeGoods[i];
            if (goods.getShellPrice() == max) {
                $goods[index++] = goods;
            }
        }

        //第四步，对对象数组排序
        for (int i = 0; i < $goods.length - 1; i++) {
            for (int j = 0; j < $goods.length - 1 - i; j++) {
                //分别获取要比较的数量
                Goods tmp1 = $goods[j];
                Goods tmp2 = $goods[j + 1];
                //注意：对象不能直接比较。
                if (tmp1.getCount() > tmp2.getCount()) {
                    $goods[j] = tmp2;
                    $goods[j + 1] = tmp1;
                }
            }
        }

        //第四步，返回数据
        Result result = new Result();
        result.setNessage("查询成功");
        result.setData($goods);//将数组保存到data
        return result;
    }

    /*5.查询库存不足10的商品信息,结果根据商品售价排序*/
    public Result storeLessThan1(){
        //第一步，知道该type的数量有多少个
        int size = 0;
        for (int i = 0; i < this.store_size; i++) {
            //取出每一个商品
            Goods goods = this.storeGoods[i];
            if (goods.getCount() < 10) {
                size++;
            }
        }
        //验证是否存在该类型的商品，如果没有，size为0，则立刻返回没有该类型商品
        if (size == 0) {
            Result result = new Result();
            result.setCode(1);
            result.setNessage("查无此库存");
        }

        //第二步，创建指定长度的数组
        Goods[] $goods = new Goods[size];

        //第三步，遍历store_goods,将对应type添加到$goods数组中
        int index = 0;
        for (int i = 0; i < this.store_size; i++) {
            //取出每一个商品
            Goods goods = this.storeGoods[i];
            if (goods.getCount() < 10) {
                $goods[index++] = goods;
            }
        }

        //第四步，对对象数组排序
        for (int i = 0; i < $goods.length - 1; i++) {
            for (int j = 0; j < $goods.length - 1 - i; j++) {
                //分别获取要比较的数量
                Goods tmp1 = $goods[j];
                Goods tmp2 = $goods[j + 1];
                //注意：对象不能直接比较。
                if (tmp1.getCount() > tmp2.getCount()) {
                    $goods[j] = tmp2;
                    $goods[j + 1] = tmp1;
                }
            }
        }

        //第四步，返回数据
        Result result = new Result();
        result.setNessage("查询成功");
        result.setData($goods);//将数组保存到data
        return result;
    }


    /*6.统计最贵的商品信息（销售价格），可能有多个*/
    public Result findByMaxSellPrice(){
        //验证是否存在该类型的商品，如果没有，size为0，则立刻返回没有该类型商品
        if (this.store_size == 0) {
            Result result = new Result();
            result.setCode(1);
            result.setNessage("暂无库存");
            return result;
        }


        //1.确定最高价格是多少
        double max = 0;
        for (int i = 0; i < this.store_size; i++) {
            Goods storeGood = this.storeGoods[i];
            if (storeGood.getShellPrice() > max) {
                max = storeGood.getShellPrice();
            }
        }

        //第一步，知道该type的数量有多少个
        int size = 0;
        for (int i = 0; i < this.store_size; i++) {
            //取出每一个商品
            Goods goods = this.storeGoods[i];
            if (goods.getShellPrice() == max) { //只要价格是最高的商品，就累加数量
                size++;
            }
        }


        //第二步，创建指定长度的数组
        Goods[] $goods = new Goods[size];

        //第三步，遍历store_goods,将对应type添加到$goods数组中
        int index = 0;
        for (int i = 0; i < this.store_size; i++) {
            //取出每一个商品
            Goods goods = this.storeGoods[i];
            if (goods.getShellPrice() == max) {
                $goods[index++] = goods;
            }
        }

        //第四步，对对象数组排序
        for (int i = 0; i < $goods.length - 1; i++) {
            for (int j = 0; j < $goods.length - 1 - i; j++) {
                //分别获取要比较的数量
                Goods tmp1 = $goods[j];
                Goods tmp2 = $goods[j + 1];
                //注意：对象不能直接比较。
                if (tmp1.getCount() > tmp2.getCount()) {
                    $goods[j] = tmp2;
                    $goods[j + 1] = tmp1;
                }
            }
        }

        //第四步，返回数据
        Result result = new Result();
        result.setNessage("查询成功");
        result.setData($goods);//将数组保存到data
        return result;
    }

    /*
    * 7.销售商品
        每次销售的商品必须对应有订单号（订单号是唯一的）
		每次销售的商品可能有多种
		销售商品时，对应的库存要减少
    * */
    public Result sellGoods(Goods[] goods) {
        if (goods == null || goods.length == 0) {
            return new Result(1, "购买商品数量必须大于等于1");
        }
        Order order = new Order();
        //设置唯一的订单编号
        order.setOrderId(atomicOrder.getAndIncrement());
        order.setGoods(goods);

        //应支付金额
        double pay = 0;
        //扣除库存
        for (int i = 0; i < this.store_size; i++) {
            Goods $goods = this.storeGoods[i];//库存的商品
            for (int j = 0; j < goods.length; j++) {
                Goods _goods = goods[j];
                //找到要销售的商品
                if ($goods.getGoodsId() == _goods.getGoodsId()) {
                    if ($goods.getCount() >= _goods.getCount()) { //库存数量充足，则扣除库存
                        $goods.setCount($goods.getCount() - _goods.getCount());
                        //计算金额
                        pay += $goods.getShellPrice() * _goods.getCount(); //商品销售单价*购买数量
                    }
                }
            }
        }
        //设置订单金额
        order.setPrice(pay);

        Result result = new Result();
        result.setNessage("购买成功");
        result.setData(order);

        //考虑为订单数组扩容
        if (this.order_size + 1 > this.orders.length) {
            //扩容
            int old_capacity = this.orders.length; //旧数组的长度
            int newLength = old_capacity + (old_capacity >> 1); //扩容1.5倍
            this.orders = Arrays.copyOf(this.orders, newLength); //将老数组的元素复制到一个长度为newLength的新数组
        }

        this.orders[order_size++] = order;
        return result;
    }

    /*
     * 8.根据订单编号查询销售的商品信息以及金额
     * */
    public Result findOrderById(long orderId) {
        //遍历商品对象数组，根据编号匹配商品
        for (int i = 0; i < this.order_size; i++) {
            Order order = this.orders[i];
            if (order.getOrderId() == orderId) { //找到了相同编号的商品
                Result result = new Result();
                result.setNessage("查询成功");

                //不动库存，复制商品数据
                Order $order = new Order();
                $order.setOrderId(order.getOrderId());
                $order.setGoods(order.getGoods()); //浅复制
                $order.setPrice(order.getPrice());

                result.setData($order);
                return result;
            }
        }
        Result fail = Result.fail();
        fail.setNessage("查无此订单信息");
        return fail;
    }
}
